package com.autumn.platform.auth.core.authc.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.autumn.platform.auth.core.authc.IAuthenticationHandler;
import com.autumn.platform.auth.core.authc.IAuthenticationListener;
import com.autumn.platform.auth.core.authc.IAuthenticationToken;
import com.autumn.platform.auth.core.authc.IAuthenticator;
import com.autumn.platform.core.context.response.IResponse;

public class BaseAuthenticator implements IAuthenticator {

    /**
     * 处理器列表
     */
    @Autowired(required = false)
    private List<IAuthenticationHandler> handlers;

    /**
     * 侦听器列表
     */
    @Autowired(required = false)
    private List<IAuthenticationListener> listeners;

    @Override
    public IResponse login(IAuthenticationToken authenticationToken) throws Exception {
        AuthenticationContext context = new AuthenticationContext();
        context.setLocked(true);
        List<IAuthenticationListener> listeners = getListeners();
        try {
            if (null != listeners) {
                for (IAuthenticationListener listener : listeners) {
                    listener.before(authenticationToken);
                }
            }
            context.setLocked(false);
            this.handler(authenticationToken, context);
            context.setLocked(true);
            if (null != listeners) {
                boolean success = context.isSuccess();

                for (IAuthenticationListener listener : listeners) {
                    if (success) {
                        listener.onSuccess(authenticationToken, context);
                    } else {
                        listener.onFailure(authenticationToken, context);
                    }
                }
            }
        } catch (Exception e) {
            if (null != listeners) {
                for (IAuthenticationListener listener : listeners) {
                    listener.onException(authenticationToken, context, e);
                }
            }
            throw e;
        }
        return context;
    }

    private void handler(IAuthenticationToken authenticationToken, AuthenticationContext context) throws Exception {
        List<IAuthenticationHandler> handlers = getHandlers();
        if (null != handlers) {
            for (IAuthenticationHandler handler : handlers) {
                handler.handler(authenticationToken, context);
                if (!context.isSuccess()) {
                    break;
                }
            }
        }
    }

    public List<IAuthenticationHandler> getHandlers() {
        return handlers;
    }

    public void setHandlers(List<IAuthenticationHandler> handlers) {
        this.handlers = handlers;
    }

    public List<IAuthenticationListener> getListeners() {
        return listeners;
    }

    public void setListeners(List<IAuthenticationListener> listeners) {
        this.listeners = listeners;
    }
}
